package xyz.jiang.asteroid.common.exception;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import xyz.jiang.asteroid.common.base.RestResponse;
import xyz.jiang.asteroid.common.enums.ServiceExceptionEnum;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@ControllerAdvice
public class GlobalServiceExceptionHandler {

    @ExceptionHandler(ServiceException.class)
    @ResponseBody
    public Object handleServiceException(ServiceException e) {
        log.error("ServiceException :",e);
        return RestResponse.error(e.getCode(),e.getMessage());
    }

    @ExceptionHandler(AccessDeniedException.class)
    @ResponseBody
    public Object handleAccessDeniedException(AccessDeniedException e){
        log.error("ServiceException :",e);
        return RestResponse.error(HttpStatus.FORBIDDEN.value(),"当前用户不允许访问！");
    }


    @ExceptionHandler(BadCredentialsException.class)
    @ResponseBody
    public RestResponse handleServiceException(BadCredentialsException e) {
        log.error("ServiceException :",e);
        return RestResponse.error(HttpStatus.UNAUTHORIZED.value(),e.getMessage());
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public RestResponse handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error("MethodArgumentNotValidException :",e);
        return handleBindingResult(e.getBindingResult());
    }

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public RestResponse handleException(Exception e) {
        log.error("Default Exception :",e);
        return RestResponse.error(500,e.getMessage());
    }

    private RestResponse handleBindingResult(BindingResult result) {
        //把异常处理为对外暴露的提示
        List<String> list = new ArrayList<>();
        if (result.hasErrors()) {
            List<ObjectError> allErrors = result.getAllErrors();
            for (ObjectError objectError : allErrors) {
                String message = objectError.getDefaultMessage();
                list.add(message);
            }
        }
        if (list.size() == 0) {
            return RestResponse.error(ServiceExceptionEnum.REQUEST_PARAM_ERROR);
        }

        return RestResponse.error(ServiceExceptionEnum.REQUEST_PARAM_ERROR.getCode(), list.toString());
    }
}